from django.contrib.gis.db import models
from django.contrib.auth.models import User
from templatetags import image_resize

# A MapTag is used to add tags to most other objects
class MapTag(models.Model):
    unique_name = models.CharField(max_length=20, unique=True)
    created_by = models.ForeignKey(User, null=True)
    
    def __unicode__ (self):
        return self.unique_name
    
    def getPhotoPlacemarksKml(self):
        kml = ''
        for p in self.photo_set.all():
            kml += p.getPlacemarkKml()
        return kml


# A MapObject is a base class that contains commom data elements used by most
# other objects on the map.
class MapObject(models.Model):
    title = models.CharField(max_length=50)
    caption = models.TextField(null=True)
    long_caption = models.TextField(null=True)
    tags = models.ManyToManyField(MapTag)
    created_by = models.ForeignKey(User, null=True)
    private = models.BooleanField(default=False)
    
    def __unicode__ (self):
        return self.title
    
    class Meta:
        abstract = True
    
    def getPlacemarkKml(self):
        pass


# A MapKey is a customized graphic/text on a map.
class MapKey(models.Model):
    unique_name = models.CharField(max_length=30, unique=True)
    title = models.CharField(max_length=50)
    description = models.TextField(null=True)
    graphic = models.ImageField(upload_to='map_keys')
    
    def __unicode__ (self):
        return self.unique_name


# A MapLayer is a base class, that can be retrieved as KML data, and overlayed on a map.
class MapLayer(models.Model):
    unique_name = models.CharField(max_length=30, unique=True)
    title = models.CharField(max_length=40)
    created_by = models.ForeignKey(User, null=True)
    tags = models.ManyToManyField(MapTag, null=True)
    
    class Meta:
        abstract = True

    def __unicode__ (self):
        return self.unique_name


# StaticMapLayer is a layer that is represented by an uploaded KML file
class StaticMapLayer(MapLayer):
    kml_file = models.FileField(upload_to='static_kml')
    map_keys = models.ManyToManyField(MapKey, null=True)


# DynamicMapLayer is a layer that is represented by a collection of tagged
# Routes, Photos, Areas, POIs, etc...
# TODO: Define Me.


# A Map consists of a list of layers, zoom elements, etc...
class Map(models.Model):
    unique_name = models.CharField(max_length=30, unique=True)
    title = models.CharField(max_length=50)
    caption = models.TextField(null=True)
    static_layers = models.ManyToManyField(StaticMapLayer)
#    dynamic_layers = 
    created_by = models.ForeignKey(User, null=True)
    center = models.PointField(srid=4326)
    zoom = models.DecimalField(max_digits=2, decimal_places=0, default=10)
    objects = models.GeoManager()


# TrackPoints are hidden elements, they make up the points in a route.  It is
# worth keeping them around for now so we can shift photos around, edit routes, etc...
class TrackPoint(models.Model):
    # Lon-Lat(-Ele) Projection SRID 4326
    location = models.PointField(srid=4326)
    location_trusted = models.BooleanField(default=False)
    time = models.DateTimeField(null=True)
    time_trusted = models.BooleanField(default=False)
    time_guessed = models.BooleanField(default=False)
    image = models.ImageField(upload_to='Images/Fullres', null=True)
    image_id = models.DecimalField(max_digits=7, decimal_places=0, null=True)
    objects = models.GeoManager()
    tags = models.ManyToManyField(MapTag, null=True)
    user = models.ForeignKey(User, null=True)

    def __unicode__ (self):
        return "(" + str(self.location.x) + ", " + str(self.location.y) + ")"


class PointOfInterest(MapObject):
    loc = models.PointField(srid=4326)
    objects = models.GeoManager()
    
    def getPlacemarkKml(self):
        kml = (
            '<Placemark id="%s">\n'
            '<name>%s</name>\n'
            '<description><![CDATA[<p>%s</p>]]></description>\n'
            '%s\n'
            '</Placemark>\n'
            ) %(self.title, self.title, self.caption, self.loc.kml)
        return kml


class Route(MapObject):
    track = models.MultiLineStringField(srid=4326)
    objects = models.GeoManager()
    
    def getPlacemarkKml(self):
        kml = (
            '<Placemark id="%s">\n'
            '<name>%s</name>\n'
            '<description><![CDATA[<p>%s</p>]]></description>\n'
            '%s\n'
            '</Placemark>\n'
            ) %(self.title, self.title, self.caption, self.track.kml)
        return kml


class Area(MapObject):
    mpoly = models.MultiPolygonField(srid=4326)
    objects = models.GeoManager()
    
    def getPlacemarkKml(self):
        kml = (
            '<Placemark id="%s">\n'
            '<name>%s</name>\n'
            '<description><![CDATA[<p>%s</p>]]></description>\n'
            '%s\n'
            '</Placemark>\n'
            ) %(self.title, self.title, self.caption, self.mpoly.kml)
        return kml


class Photo(MapObject):
    rank = models.DecimalField(default=0, decimal_places=0, max_digits=2)
    location = models.PointField(null=True, srid=4326)
    timetaken = models.DateTimeField(null=True)
    subjectlocation = models.PointField(null=True, srid=4326)
    image = models.ImageField(upload_to='Images/Fullres')
    photographer = models.CharField(null=True, max_length=128)
    objects = models.GeoManager()
    
    def getPlacemarkKml(self):
        kml = (
            '<Placemark id="%s">\n'
            '<name>%s</name>\n'
            '<description><![CDATA[<p>%s</p><p><img src="%s"/></p>]]></description>\n'
            '%s\n'
            '</Placemark>\n'
            ) %(self.title, self.title, self.caption, image_resize.small(self.image), self.location.kml)
        return kml
